package br.com.actionsystem.gdp.telas;

import br.com.actionsystem.gdp.dao.AtividadeDao;
import br.com.actionsystem.gdp.dao.CategoriaDaoImpl;
import br.com.actionsystem.gdp.dao.IntCategoriaDao;
import br.com.actionsystem.gdp.dao.PagamentoDaoImpl;
import br.com.actionsystem.gdp.dao.intAtividadeDao;
import br.com.actionsystem.gdp.modelo.AutoCompletar;
import br.com.actionsystem.gdp.modelo.Categoria;
import br.com.actionsystem.gdp.modelo.Despesa;
import br.com.actionsystem.gdp.modelo.Historico;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.text.DecimalFormat;
import java.text.ParseException;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFormattedTextField;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.text.NumberFormatter;
import br.com.actionsystem.gdp.modelo.Periodo;
import br.com.actionsystem.gdp.util.DaoException;
import br.com.actionsystem.gdp.util.LayoutHelp;
import br.com.actionsystem.gdp.util.TableModelDespesas;
import br.com.actionsystem.gdp.util.TextNumber;
import com.michaelbaranov.microba.calendar.DatePicker;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.beans.PropertyVetoException;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import javax.swing.JCheckBox;
import javax.swing.JDesktopPane;
import javax.swing.JOptionPane;

public class Despesas extends AbstratcTelas {

    DecimalFormat decimalFormat = new DecimalFormat("###,###,##0.00");
    private JTextField descricaoTf = null;
    private JComboBox nmParcelasCb = null;
    private JComboBox periodoCb = null;
    private JComboBox categoriaCb = null;
    private JFormattedTextField valorTf = null;
    private DatePicker vencimentoDp = null;
    private JTable table = null;
    private JCheckBox pagar = null;
    private JScrollPane scroll = new JScrollPane();
    private String[] colunas = {"Descrição", "Vencimento", "Parcelas", "Período", "Valor"};
    private List<Categoria> categorias = null;
    private CategoriaDaoImpl categoriaDao = new CategoriaDaoImpl();
    intAtividadeDao dao = new AtividadeDao();
    PagamentoDaoImpl pagamentosDao = new PagamentoDaoImpl();
    Despesa despesa = new Despesa();
    List<Despesa> lista = null;
    public JLabel valor;
    ConfirmaPagamentoJIntFr confirma = null;

    public Despesas() {
        super("Despesas");
        iniciar();
        Dimension dim = new Dimension(680, 450);
        setSize(dim);
        setDefaultCloseOperation(Despesas.HIDE_ON_CLOSE);
        acoesDosBotoes();
    }

    private void iniciar() {
        JPanel geral = new JPanel();
        geral.setLayout(new GridBagLayout());
        geral.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        getCabecalhoPn().add(new JLabel("Descrição *"), LayoutHelp.addLabel());
        getCabecalhoPn().add(getDescricaoTf(), LayoutHelp.addComponent3());

        getCabecalhoPn().add(new JLabel("Valor *"), LayoutHelp.addLabel());
        getCabecalhoPn().add(getValorTf(), LayoutHelp.addComponentFinal());
        getCabecalhoPn().add(new JLabel("Núm parcelas:"), LayoutHelp.addLabel());
        getCabecalhoPn().add(getNmParcelasCb(), LayoutHelp.addComponent1());
        getCabecalhoPn().add(new JLabel("Período:"), LayoutHelp.addLabel());
        getCabecalhoPn().add(getPeriodoCb(), LayoutHelp.addComponent1());
        getCabecalhoPn().add(new JLabel("Vencimento:"), LayoutHelp.addLabel());
        getCabecalhoPn().add(getVencimentoDp(), LayoutHelp.addComponentFinal());
        getCabecalhoPn().add(new JLabel("Categoria *"), LayoutHelp.addLabel());
        getCabecalhoPn().add(getCategoriaCb(), LayoutHelp.addComponent2());
        getCabecalhoPn().add(getPagar(), LayoutHelp.addComponent3());

        Dimension dim = new Dimension(110, 27);
        for (int i = 0; i < getCabecalhoPn().getComponentCount(); i++) {
            JComponent component = (JComponent) getCabecalhoPn().getComponent(i);
            if (!(component instanceof JLabel)) {
                getCabecalhoPn().getComponent(i).setMinimumSize(dim);
                getCabecalhoPn().getComponent(i).setPreferredSize(dim);
            }
            component.setFont(fontBond);
        }
        getCabecalhoPn().add(new JLabel(), LayoutHelp.addComponentFinal());
        getCabecalhoPn().add(getBotaoPn(), LayoutHelp.addComponentFinal());
        geral.add(getCabecalhoPn(), LayoutHelp.addComponentFinal());
        scroll.setViewportView(getTable());
        scroll.setMinimumSize(new Dimension(400, 200));
        scroll.setPreferredSize(new Dimension(400, 200));
        geral.add(scroll, LayoutHelp.addComponentFinal());
        getContentPane().add(geral);

    }

    public void atualizaTabela() {
        lista = dao.listaDespesa();
        TableModelDespesas model = new TableModelDespesas(lista);
        table.setModel(model);
        scroll.repaint();
    }

    public void acoesDosBotoes() {
        getSalvarBt().setToolTipText("Clique aqui para salvar sua despesa !");
        getSalvarBt().addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                carregaDespesas();
                Calendar c = Calendar.getInstance();
                c.setTime(despesa.getDataVencimento());
                Periodo periodo = despesa.getPeriodo();

                try {

                    boolean existe = despesa.getIdAtividade() != 0;
                    if (!ValidaCampos()) {
                        return;
                    }
                    dao.salvar(despesa);
                    Historico aPagar = null;
                    if (!existe) {
                        if (despesa.getNumParcela() == 0) {
                            for (int i = 0; i < 12; i++) {
                                Historico h = new Historico();
                                h.setDataPagamento(c.getTime());
                                h.setIdAtividadeFK(despesa);
                                h.setValor(despesa.getValorEstimado());
                                h.setNumeroParcela(i + 1);
                                c.add(periodo.caledar, 1);
                                pagamentosDao.salvaPagamento(h);
                                if (i == 0) {
                                    aPagar = h;
                                }

                            }
                        } else {
                            for (int i = 0; i < despesa.getNumParcela(); i++) {
                                Historico h = new Historico();
                                h.setDataPagamento(c.getTime());
                                h.setIdAtividadeFK(despesa);
                                h.setValor(despesa.getValorEstimado());
                                h.setNumeroParcela(i + 1);
                                c.add(periodo.caledar, 1);
                                pagamentosDao.salvaPagamento(h);
                                if (i == 0) {
                                    aPagar = h;
                                }

                            }
                        }
                    }

                    if (getPagar().isSelected() && aPagar != null) {
                        getConfirma().preencheTela(aPagar);
                        getConfirma().setVisible(true);
                        limpaTela();
                    }
                    despesa = new Despesa();
                    atualizaTabela();
                    limpaTela();

                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        });

        getNovoBt().setToolTipText("Clique aqui para criar uma nova despesa !");
        getNovoBt().addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                limpaTela();
                despesa = new Despesa();

            }
        });

        getExcluir().setToolTipText("Clique aqui para excluir uma despesa ! ");
        getExcluir().addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {

                if (despesa == null || despesa.getIdAtividade() == 0) {

                    JOptionPane.showMessageDialog(null, "Selecione uma linha para que ocorra a exclusão !");
                    return;

                }



                Object opcoes[] = {"Sim", "Não"};
                int op = JOptionPane.showInternalOptionDialog(Despesas.this,
                        "Você tem certeza que quer apagar essa reserva ? tem certeza mesmo?", "Aviso",
                        JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, opcoes, null);
                if (op == 0) {
                    try {
                        dao.delete(despesa);
                        pagamentosDao.deleteHistorico(despesa);
                        despesa = null;
                        limpaTela();

                        atualizaTabela();

                    } catch (DaoException ex) {
                        JOptionPane.showMessageDialog(null, ex.getMessage());
                        ex.printStackTrace();
                    }

                }

            }
        });


    }

    public static void main(String[] args) {
        new Despesas().setVisible(true);
    }

    private JTextField getDescricaoTf() {
        if (descricaoTf == null) {
            descricaoTf = new JTextField("", 25);
            descricaoTf.setToolTipText("Digite um nome para sua despesa !");
            descricaoTf.setSize(120, 27);
        }

        return descricaoTf;
    }

    private JComboBox getNmParcelasCb() {
        if (nmParcelasCb == null) {
            nmParcelasCb = new JComboBox();
            nmParcelasCb.setToolTipText("Selecione o numero de parcelas que você deseja pagar sua despesa !");
            nmParcelasCb.addItem("Permanente");
            for (int i = 1; i <=
                    120; i++) {
                nmParcelasCb.addItem(i);
            }

        }
        return nmParcelasCb;
    }

    private JComboBox getPeriodoCb() {
        if (periodoCb == null) {
            periodoCb = new JComboBox();
            periodoCb.setToolTipText("Selecione o periodo que você deseja pagar sua despesa !");
            for (Periodo p : Periodo.values()) {
                periodoCb.addItem(p);
            }

        }
        return periodoCb;
    }

    public ConfirmaPagamentoJIntFr getConfirma() {
        if (confirma == null) {
            confirma = new ConfirmaPagamentoJIntFr();
            JDesktopPane desk = getDesktopPane();
            desk.add(getConfirma());
        }
        return confirma;
    }

    private JComboBox getCategoriaCb() {
        if (categoriaCb == null) {
            categoriaCb = new JComboBox();
            categoriaCb.setToolTipText("Selecione em que categoria você deseja salvar sua despesa !");
            categoriaCb.setEditable(true);
            try {
                categorias = categoriaDao.listarTodas();
            } catch (DaoException ex) {
                JOptionPane.showMessageDialog(null, ex.getMessage());
                ex.printStackTrace();
            }
            new AutoCompletar(categoriaCb);
            categoriaCb.addItem("");
            for (Categoria c : categorias) {
                categoriaCb.addItem(c);
            }

        }
        return categoriaCb;
    }

    private JFormattedTextField getValorTf() {
        if (valorTf == null) {

            NumberFormatter numberFormat = new NumberFormatter(decimalFormat) {

                @Override
                public Object stringToValue(
                        String text) throws ParseException {
                    if (text.equals("0,00") || text.equals("0.00") || text.equals("")) {
                        return null;
                    } else {
                        return super.stringToValue(text);
                    }

                }
            };
            numberFormat.setAllowsInvalid(true);
            valorTf =
                    new JFormattedTextField(numberFormat);
            valorTf.setHorizontalAlignment(javax.swing.JTextField.RIGHT);
            valorTf.setDocument(new TextNumber());
        }
        valorTf.setToolTipText("Digite um valor para sua despesa !");
        return valorTf;
    }

    private DatePicker getVencimentoDp() {
        if (vencimentoDp == null) {
            vencimentoDp = new DatePicker();
            vencimentoDp.setShowNoneButton(false);
        }

        return vencimentoDp;
    }

    public IntCategoriaDao getCategoriaDao() {
        return categoriaDao;
    }

    public void setCategoriaDao(CategoriaDaoImpl categoriaDao) {
        this.categoriaDao = categoriaDao;
    }

    public List<Categoria> getCategorias() {
        return categorias;
    }

    public void setCategorias(List<Categoria> categorias) {
        this.categorias = categorias;
    }

    public String[] getColunas() {
        return colunas;
    }

    public void setColunas(String[] colunas) {
        this.colunas = colunas;
    }

    public Despesa getDespesa() {
        return despesa;
    }

    public void setDespesa(Despesa despesa) {
        this.despesa = despesa;
    }

    public JScrollPane getScroll() {
        return scroll;
    }

    public void setScroll(JScrollPane scroll) {
        this.scroll = scroll;
    }

    public JCheckBox getPagar() {
        if (pagar == null) {
            if (pagar == null) {
                pagar = new JCheckBox("Pagar agora");
                pagar.setToolTipText("Para pagar agora selecione aqui !");
                pagar.setSize(10, 10);
            }
        }
        return pagar;
    }

    public JTable getTable() {
        lista = dao.listaDespesa();
        TableModelDespesas model = new TableModelDespesas(lista);
        table = new JTable(model);
        table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        //table.setRowSelectionInterval(0, 0);
        table.setAutoscrolls(true);
        table.getColumnModel().getColumn(0).setPreferredWidth(180);
        table.getColumnModel().getColumn(1).setPreferredWidth(58);
        table.getColumnModel().getColumn(2).setPreferredWidth(38);
        table.getColumnModel().getColumn(3).setPreferredWidth(38);
        table.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseReleased(MouseEvent e) {
                int row = table.getSelectedRow();
                despesa = lista.get(row);
                descarregaDespesas();
                pagar.setEnabled(false);
            }
        });

        return table;
    }

    public void carregaDespesas() {
        String s = valorTf.getText().replaceAll("\\.", "").replaceAll("\\,", ".");
        despesa.setValorEstimado(Float.parseFloat(s.equals("") ? "0.0" : s));
        despesa.setDescricao(descricaoTf.getText());
        despesa.setNumParcela(nmParcelasCb.getSelectedIndex());
        despesa.setTipoPeriodico(nmParcelasCb.getSelectedIndex() != 1);
        despesa.setPeriodo((Periodo) periodoCb.getSelectedItem());
        despesa.setDataVencimento(vencimentoDp.getDate());

        if (categoriaCb.getSelectedIndex() > 0) {
            despesa.setCategoria((Categoria) categoriaCb.getSelectedItem());
        } else if (categoriaCb.getSelectedIndex() == -1) {
            Categoria c = new Categoria((String) categoriaCb.getSelectedItem());
            categoriaDao.salvar(c);
            despesa.setCategoria(c);
            categorias.add(c);
            categoriaCb.addItem(c);
        }

    }

    public void descarregaDespesas() {
        valorTf.setText(decimalFormat.format(despesa.getValorEstimado()));
        descricaoTf.setText("" + (despesa.getDescricao()));
        nmParcelasCb.setSelectedIndex(despesa.getNumParcela());
        periodoCb.setSelectedIndex(despesa.getPeriodo().ordinal());
        categoriaCb.setSelectedItem(despesa.getCategoria());
        try {
            vencimentoDp.setDate(despesa.getDataVencimento());
        } catch (PropertyVetoException ex) {
            ex.printStackTrace();
        }


    }

    public void limpaTela() {
        valorTf.setText("");
        descricaoTf.setText("");
        nmParcelasCb.setSelectedIndex(0);
        periodoCb.setSelectedIndex(0);
        categoriaCb.setSelectedIndex(0);
        pagar.setSelected(false);
        pagar.setEnabled(true);
        try {
            vencimentoDp.setDate(new Date());
        } catch (PropertyVetoException ex) {
            ex.printStackTrace();
        }
    }

    public boolean ValidaCampos() {
        String msg = "Voce precisa preencher os seguintes campos : ";

        if (despesa.getDescricao().equals("")) {
            msg += " Descrição ";
        }
        if (despesa.getCategoria() == null) {
            msg += " Categoria ";
        }
        if (despesa.getValorEstimado() == 0.0) {
            msg += " Valor estimado";
        }

        if (msg.equals("Voce precisa preencher os seguintes campos : ")) {
            return true;
        } else {
            JOptionPane.showMessageDialog(null, msg);
            return false;
        }
    }
}
